// <copyright file="InterpolationField.cs" company="MetricGR">
// Copyright MetricGR. All rights reserved.
// </copyright>
// <author>MAGNA\Andtheflux</author>
// <date>2015-07-24 13:40:27Z</date>
using System;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Reflection;
using Microsoft.SharePoint.Security;
using System.Security.Permissions;

namespace MetricGR.Interpolation.Components
{
    /// <summary>
    /// Custom field type InterpolationField
    /// DisplayName: Interpolation Field
    /// Description: Calculated field used to construct HTML based on a list items values.
    /// </summary>
    public class InterpolationField : SPFieldMultiLineText
    {
        public InterpolationField(SPFieldCollection fields, string fieldName) : base(fields, fieldName) { }

        public InterpolationField(SPFieldCollection fields, string typeName, string displayName) : base(fields, typeName, displayName) { }

        #region FIX for Get and Set Custom Property
        public void SetFieldAttribute(string attribute, string value)
        {
            Type baseType;
            BindingFlags flags;
            MethodInfo mi;

            baseType = typeof(InterpolationField);
            flags = BindingFlags.Instance | BindingFlags.NonPublic;
            mi = baseType.GetMethod("SetFieldAttributeValue", flags);
            mi.Invoke(this, new object[] { attribute, value });
        }

        public override string GetProperty(string propertyName)
        {
            string value = string.Empty;
            if (propertyName.Equals(Common.FieldInterpolationProperty))
            {
                value = this.GetFieldAttribute(propertyName);
            }
            else
            {
                value = base.GetProperty(propertyName);
            }
            return value;
        }

        public string GetFieldAttribute(string attribute)
        {
            Type baseType;
            BindingFlags flags;
            MethodInfo mi;

            baseType = typeof(InterpolationField);
            flags = BindingFlags.Instance | BindingFlags.NonPublic;
            mi = baseType.GetMethod("GetFieldAttributeValue", flags, null, new Type[] { typeof(String) }, null);
            object obj = mi.Invoke(this, new object[] { attribute });

            if (obj == null)
            {
                return "";
            }
            else
            {
                return obj.ToString();
            }
        }
        #endregion

        #region Overrrides

        public override void OnAdded(SPAddFieldOptions op)
        {
            base.OnAdded(op);

            InterpolationField.AllItemsUpdateField(this.ParentList, this);

            // add the list item event receiver to the list
            Common.AddEventReceiver(this.ParentList, typeof(InterpolationIER).ToString());
        }

        public override void OnDeleting()
        {
            base.OnDeleting();

            // check to see if this is the last "template token" field ans if so delete the event receiver
            Common.RemoveEventRecieverFromList(this.ParentList, typeof(InterpolationIER).ToString());
        }

        public override BaseFieldControl FieldRenderingControl
        {
            [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
            get
            {
                BaseFieldControl fieldControl = new InterpolationFieldControl();
                fieldControl.FieldName = this.InternalName;

                return fieldControl;
            }
        }

        public override void OnUpdated()
        {
            base.OnUpdated();

            InterpolationField.AllItemsUpdateField(this.ParentList, this);
        }

        private static void AllItemsUpdateField(SPList list, SPField field)
        {
            foreach (SPListItem item in list.Items)
            {
                string value = InterpolationFieldControl.GetItemFieldInterpolatedString(list.ParentWeb.Site, list.ParentWeb, list, item, field);
                item[field.Id] = value;
                item.SystemUpdate(false);
            }
        }

        public override string GetFieldValueAsHtml(object value)
        {
            string text = this.GetFieldValueAsText(value);
            string html = System.Web.HttpUtility.HtmlDecode(text);
            return html;
        }

        #endregion Overrrides
    }

    [DataContract]
    public class InterpolationFieldObject
    {
        [DataMember]
        public string InterpolationString = string.Empty;

        public InterpolationFieldObject() { }

        public InterpolationFieldObject(string JsonValue)
        {
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(InterpolationFieldObject));
            MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(JsonValue));
            InterpolationFieldObject obj = (InterpolationFieldObject)js.ReadObject(stream);

            this.InterpolationString = obj.InterpolationString;
        }

        public string ToJSON()
        {
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(InterpolationFieldObject));
            MemoryStream stream = new MemoryStream();
            js.WriteObject(stream, this);
            stream.Position = 0;
            string value = new StreamReader(stream).ReadToEnd();
            return value;
        }
    }
}

